package com.clippick;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.StrictMode;
import android.provider.MediaStore;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.text.ClipboardManager;
import android.util.Log;
//import android.view.View;
import android.view.Window;
//import android.widget.AdapterView;
//import android.widget.AdapterView.OnItemClickListener;
import co.kr.clippick.R;

import com.clippick.api.GetApi;
import com.clippick.clipboard.PollingService;
import com.clippick.clipboard.ShorcutNotificationService;
import com.clippick.common.GlobalValue;
import com.clippick.common.Toasts;
import com.clippick.common.Utils;
import com.clippick.database.FeedOrderDBAdapter;
import com.clippick.database.HistoryDBAdapter;
import com.clippick.history.FullScreenImageViewer;
import com.clippick.history.HistoryFragment;

@SuppressWarnings("deprecation")
public class MainActivity extends FragmentActivity {
	// common
	private Context mContext;
	private TabFragment tabFragment;
	private ConnectivityManager manager;

	// data:info
	private SharedPreferences pref;
	private SharedPreferences.Editor editor;

	// system cliboard
	private ClipboardManager systemClipboard;

	/** local database manager */
	private HistoryDBAdapter dbManager;
	private FeedOrderDBAdapter feedOrderDbManager;

	// ping-pong test
	private Thread pingThread;
	private boolean isPingAlive = false;

	@SuppressWarnings("deprecation")
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mContext = this;

		if (Utils.isAndroidLowerThanICS()) {
			// remove title
			requestWindowFeature(Window.FEATURE_NO_TITLE);
		} else {
			StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
					.permitAll().build();
			StrictMode.setThreadPolicy(policy);
		}

		Log.i("activity", "mainActivity onCreate()");
		manager = (ConnectivityManager) mContext
				.getSystemService(Context.CONNECTIVITY_SERVICE);

		// prevent unauthorized user to show MainActivity
		if (GlobalValue.USER_ID.equals("")) {
			Intent intent = new Intent(mContext, LoginActivity.class);
			startActivity(intent);
			finish();
		}

		// preferences
		pref = mContext.getSharedPreferences(GlobalValue.KEY,
				Context.MODE_PRIVATE);
		editor = mContext.getSharedPreferences(GlobalValue.KEY,
				Context.MODE_PRIVATE).edit();

		// system clipboard
		systemClipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);

		// set empty clipboard
		systemClipboard.setText("");

		// open local database manager
		/**
		String dbID = GlobalValue.USER_ID.replaceAll("@", "_")
				.replaceAll(".", "_").replaceAll("-", "_");
		
		dbManager = new HistoryDBAdapter(this, dbID);
		dbManager.open();

		// open 'order' database manager
		feedOrderDbManager = new FeedOrderDBAdapter(this, dbID);
		feedOrderDbManager.open();
		*/
		
		// set initial fragment view: historyFragment();
		FragmentManager fm = getSupportFragmentManager();
		tabFragment = (TabFragment) fm.findFragmentById(R.id.fragment_tab);
		tabFragment.historyFragment();

		// start screen on/off monitor
		GlobalValue.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_ON);
		GlobalValue.saveFirstSyncComplete(mContext, true);

		// start background service
		if (pref.getBoolean("autoSync", false)) {
			startClipService();
		}

		startForegroundNotification();

		// register network status broadcast receiver

		// if (getIntent().getExtras() != null)
		// if (getIntent().getExtras().getBoolean("notification")) {
		// try {
		// // ClipPickListener.client.disconnect();
		// } catch (IOException e) {
		// // TODO Auto-generated catch block
		// e.printStackTrace();
		// }
		// }

		// Intent checkSyncIntent = new Intent();
		// checkSyncIntent.setAction("com.clippick.CheckSync");
		// sendBroadcast(checkSyncIntent);
	}

	// access from StarFragment.class and HistoryFragment.class
	public HistoryDBAdapter getLocalDb() {
		return dbManager;
	}

	// access from StarFragment.class and HistoryFragment.class
	public FeedOrderDBAdapter getLocalOrderDb() {
		return feedOrderDbManager;
	}

	// access from StarFragment.class and HistoryFragment.class
	// still using deprecated Class to support such older version of Android
	// without crash
	@SuppressWarnings("deprecation")
	public ClipboardManager getSystemClipboard() {
		return systemClipboard;
	}

	// memo clip
	public void insertMemoClip(String content) {
		new HttpTask().execute(content, "", "memo");
	}

	// access from setting: animate icon to rotate
	public void rotateIcon(int id) {
		tabFragment.rotateIcon(id);
	}

	// handle indicator with network
	public void handleIndicator(boolean value) {
		tabFragment.handleIndicator(value);
	}

	// it will be called by clicking the star button on the list item
	public void setStar(Map<?, ?> item) {
		String starValue = item.get(HistoryDBAdapter.KEY_DB_KEEPBOX).toString();
		String clipIndex = item.get(HistoryDBAdapter.KEY_DB_NO).toString();
		if (starValue.equals("1")) {
			starValue = "0";
		} else {
			starValue = "1";
		}
		new HttpTask().execute(clipIndex, starValue, "star");
	}

	public void deleteClip(String clipIndex) {
		new HttpTask().execute(clipIndex, "", "delete");
	}

	// user can see image by full screen
	public void showFullScreenViewer(String path) {
		Intent intent = new Intent(mContext, FullScreenImageViewer.class);
		intent.putExtra("path", path);
		startActivity(intent);
		overridePendingTransition(android.R.anim.fade_in,
				android.R.anim.fade_out);
	}

	// user can save image
	public void sendImageGallery(Map item) {
		String filePath = item.get(FeedOrderDBAdapter.KEY_DB_TEXT_PATH)
				.toString();
		String imageUrl = item.get(FeedOrderDBAdapter.KEY_DB_IMAGE_URL)
				.toString();

		File file = new File(filePath);
		String fileName = filePath.substring(filePath.lastIndexOf("/") + 1,
				filePath.length());

		if (file.isFile() == false) {
			Utils.downloadFromUrl(imageUrl, filePath);
		}

		if (isImageInGallery(filePath) == false) {
			try {
				if (android.os.Build.PRODUCT.toUpperCase().contains("HTC")) {
					Uri uri = Uri.parse("file://" + filePath);

					Intent intent = new Intent(
							Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
					intent.setData(uri);
					sendBroadcast(intent);
				} else {
					insertGallery(filePath, file, fileName);
				}
			} catch (Exception e) {
				Log.e("insertImage", "Error writing file", e);
			}
		}
	}

	/** 이미지 갤러리에 존재하는지 확인 */
	private boolean isImageInGallery(String _filePath) {
		String[] proj = { MediaStore.Images.Media._ID,
				MediaStore.Images.Media.DATA,
				MediaStore.Images.Media.DISPLAY_NAME,
				MediaStore.Images.Media.SIZE, MediaStore.Images.Media.TITLE };

		ContentResolver contentResolver = getContentResolver();
		Cursor imageCursor = contentResolver.query(
				MediaStore.Images.Media.EXTERNAL_CONTENT_URI, proj,
				MediaStore.Images.Media.DATA + "='" + _filePath + "'", null,
				null);

		if (imageCursor != null && imageCursor.moveToFirst()) {
			if (imageCursor.getCount() > 0) {

				imageCursor.close();
				return true;
			}
		}
		imageCursor.close();
		return false;
	}

	/** 이미지 갤러리에 저장 */
	private void insertGallery(String _filePath, File file, String fileName) {

		ContentValues values = new ContentValues();

		values.clear();
		values.put(MediaStore.Images.Media.TITLE, _filePath);
		values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
		values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
		values.put(MediaStore.Images.Media.DISPLAY_NAME, fileName);

		ContentResolver contentResolver = getContentResolver();

		try {
			Uri uri = contentResolver.insert(
					MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);

			if (uri == null) {
				// Exception 객체 Throw 하기
			} else {
				sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
						uri));
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/** HTTP Request from background */
	class HttpTask extends AsyncTask<String, String, String> {
		ProgressDialog mProgress;
		String id = "";
		String result = "";
		Map<String, String> starResult = new HashMap<String, String>();

		protected void onPreExecute() {
			mProgress = new ProgressDialog(mContext);
			mProgress.setMessage("Loading");
			// mProgress.show();

			tabFragment.handleIndicator(true);
		}

		@Override
		protected String doInBackground(String... params) {
			GetApi api = new GetApi();
			id = params[2];

			try {
				if (params[2].equals("star")) {
					starResult = api.setStarApi(params[0], params[1]);
				} else if (params[2].equals("delete")) {
					api.deleteClipApi(params[0]);
				} else if (params[2].equals("image")) {
					// api.insertImageClip(params[0], imageFile);
				} else if (params[2].equals("memo")) {
					api.insertNewClip(params[0], "0");
				} else if (params[2].equals("invite")) {
					result = api.inviteTinyUrlApi();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

			return null;
		}

		protected void onPostExecute(String unused) {
			// mProgress.dismiss();
			tabFragment.handleIndicator(false);
			if (id.equals("star")) {
				JSONObject json = new JSONObject(starResult);

				try {
					int returnCode = Integer.parseInt(json
							.getString("returnCode"));
					switch (returnCode) {
					case 200:

						break;
					default:
						tabFragment.updateFeed();
						Toasts.showToast(mContext,
								json.getString("returnMessage"));
						break;
					}

				} catch (NumberFormatException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (JSONException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

			// send tiny url to friends
			if (id.equals("invite")) {
				sendFriendUrl(result);
			}
		}
	}

	/* invite */
	public void getTinyUrl() {
		new HttpTask().execute("", "", "invite");
	}

	private void sendFriendUrl(String tinyUrl) {
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_SEND);
		intent.putExtra(Intent.EXTRA_TEXT,
				"you can copy paste anywhere like post-it!\n" + tinyUrl);
		intent.setType("text/plain");
		startActivity(Intent.createChooser(intent, "send to"));
	}

	/** SharedMenu를 통해서 이미지를 공유하는지 확인 */
	private void checkSharedMenu() {
		if (Intent.ACTION_SEND.equals(getIntent().getAction())) {
			if (GlobalValue.USER_ID.equals("")) {
				Toasts.showToast(mContext, "please login");
			} else {
				Intent intent = new Intent();
				intent.setAction("com.clippick.TransferImage");
				intent.putExtras(getIntent());
				sendBroadcast(intent);
			}

			finish();
		}
	}

	public String parseUriToFileName(Uri uri) {
		String selectedImagePath = null;
		String filemanagerPath = uri.getPath();

		String[] projection = { MediaStore.Images.Media.DATA };
		@SuppressWarnings("deprecation")
		Cursor cursor = managedQuery(uri, projection, null, null, null);

		if (cursor != null) {
			// Here you will get a null pointer if cursor is null
			// This can be if you used OI file manager for picking the media
			int column_index = cursor
					.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
			cursor.moveToFirst();
			selectedImagePath = cursor.getString(column_index);
		}

		if (selectedImagePath != null) {
			return selectedImagePath;
		} else if (filemanagerPath != null) {
			return filemanagerPath;
		}
		return null;
	}

	/** start monitor polling system clipboard on background */
	private void startClipService() {
		Intent intent = new Intent(mContext, PollingService.class);
		startService(intent);
	}

	private void startForegroundNotification() {
		Intent intent = new Intent(mContext, ShorcutNotificationService.class);
		if (pref.getBoolean("showNotif", false)) {
			startService(intent);
		} else {
			stopService(intent);
		}
	}

	public void onPause() {
		super.onPause();
		isPingAlive = false;
		pingThread.interrupt();

		int nBackStatus = GlobalValue.getBackgroundOn(this);
		switch (nBackStatus) {
		case GlobalValue.ACT_ON_SERVICE_OFF:
			GlobalValue.saveBackgroundPref(this,
					GlobalValue.ACT_OFF_SERVICE_OFF);
			break;
		case GlobalValue.ACT_ON_SERVICE_ON:
			GlobalValue
					.saveBackgroundPref(this, GlobalValue.ACT_OFF_SERVICE_ON);
			break;
		default:
			break;
		}
	}

	public void onDestroy() {
		super.onDestroy();
		// if (dbManager != null)
		// dbManager.close();
		//
		// if (feedOrderDbManager != null)
		// feedOrderDbManager.close();

		isPingAlive = false;
		pingThread.interrupt();
	}

	/** 화면 켜짐, 꺼짐 감시 시작 */
	public void onResume() {
		super.onResume();
		
		/**
		String dbID = GlobalValue.USER_ID.replaceAll("@", "_")
				.replaceAll(".", "_").replaceAll("-", "_");

		dbManager = new HistoryDBAdapter(this, dbID);
		dbManager.open();

		// open 'order' database manager
		feedOrderDbManager = new FeedOrderDBAdapter(this, dbID);
		feedOrderDbManager.open();
		*/
		
		Log.i("activity", "mainActivity onResume()");
		int nBackStatus = GlobalValue.getBackgroundOn(this);
		switch (nBackStatus) {
		case GlobalValue.ACT_OFF_SERVICE_OFF:
			GlobalValue
					.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_OFF);
			break;
		case GlobalValue.ACT_OFF_SERVICE_ON:
			GlobalValue.saveBackgroundPref(this, GlobalValue.ACT_ON_SERVICE_ON);
			break;
		default:
			break;
		}

		// check image shared from SharedMenu
		checkSharedMenu();

		// prevent unauthorized user to show MainActivity
		if (GlobalValue.USER_ID.equals("")) {
			Intent intent = new Intent(mContext, LoginActivity.class);
			startActivity(intent);
			finish();
		}

		this.isPingAlive = true;
		pingThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (isPingAlive) {
					GetApi api = new GetApi();
					api.sendPing();
					try {
						Thread.sleep(7500);
					} catch (InterruptedException ignored) {

					}
				}
			}
		});

		pingThread.start();

		// send broadcast to do connect longpolling
		if (Utils.checkNetwokState(manager)) {
			if (PollingService.CONNECTED_COUNT == 0) {
				Intent intent = new Intent();
				intent.setAction("com.clippick.LongPoll");
				sendBroadcast(intent);
			}
		}
	}

	// close memo before finish();
	public void onBackPressed() {
		if (HistoryFragment.isMemoClose) {
			super.onBackPressed();
			finish();
		} else {
			HistoryFragment.closeMemo();
		}
	}

	/* network status broadcast receiver */
	public BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
		@Override
		public void onReceive(Context context, Intent intent) {

			@SuppressWarnings("deprecation")
			NetworkInfo currentNetworkInfo = (NetworkInfo) intent
					.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);

			// do specific task(s) based on the current network state, such
			// as enabling queuing of HTTP requests when currentNetworkInfo is
			// connected etc.
			if (currentNetworkInfo.isConnected()) {

			} else {

			}
		}
	};
}
